/**
 * File: ThreadedDataCollector.java
 * TCSS 422 Team Project 1
 * Autumn 2009
 * Team Members: Darin Cyr, Kirk Leonard, John Patanian
 */
package multiThread;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.Map.Entry;

/**
 * Finds how many times a keyword appears in the web pages.  
 * It uses a hashmap of keyword/hit pairs to keep track.
 * @author Darin Cyr
 * @author Kirk Leonard
 * @author John Patanian
 * @version Autumn 2009
 */
public class ThreadedDataCollector implements Runnable
{
  /**
   * Sleep time for the thread.
   */
  private static final int MAX_SLEEP_TIME = 100;
  
  /**
  * Collection for holding the keywords and hits.
  */

  private Map<String, Integer> my_map;
  
  private Buffer<String> the_page_buffer;

  /**
  * The page count.
  */
  private int my_page_count;

  /**
  * The number of words found.
  */
  private int my_number_of_words;

  /**
  * Constructor takes pageCount and uses it to generate filenames that it will open.
  * @param the_page_buffer The cached web pages
  */
  public ThreadedDataCollector(final Buffer<String> the_page_buffer) 
  {
    //my_page_count = the_page_count;
    this.the_page_buffer = the_page_buffer;
    my_map = new HashMap<String, Integer>();
    my_page_count = 0;
    my_number_of_words = 0;
    loadKeyWords();
  }

  /**
  * Opens each page that has been cached locally and looks for keywords.
  * @param the_current_page The page to process.
  */
  private void processPage(final String the_current_page) 
  {
    final String this_page = the_current_page;
    final Scanner input = new Scanner(this_page);

    while (input.hasNext()) 
    {
      my_number_of_words++;
      final String a_word = input.next().toLowerCase().replaceAll("[^A-Za-z0-9]", "");

      if (my_map.containsKey(a_word)) 
      {
        my_map.put(a_word, my_map.get(a_word) + 1);
      }
    }
      
    input.close();
  }

  /**
  * Used to calculate the average number of keywords per page.
  * @return Returns the number of words.
  */
  public int getNumWords() 
  {
    return my_number_of_words;
  }

  /**
  * Used so the ui can print out a list of keywords and how often they're found.
  * @return returns a set with word counts.
  */
  public Set<Entry<String, Integer>> getWordCounts()
  {
    return my_map.entrySet();
  }

  /**
   * Load the key words from keywords.txt.
   */
  private void loadKeyWords() 
  {
    Scanner word_scanner = null;
    
    try 
    {
      word_scanner = new Scanner(new File("keyWords.txt"));
    }
    catch (final FileNotFoundException e) 
    {
      System.out.println(e);
    }

    while (word_scanner.hasNext())
    {
      my_map.put(word_scanner.next(), new Integer(0));
    }
    
    word_scanner.close();
  }
  
  /**
   * Returns the number of pages collected.
   * @return The number of pages.
   */
  public int numPagesCollected()
  {
    return my_page_count;
  }
  
  /**
   * Implementation of the Runnable interface. 
   */
  public void run() 
  {
    try 
    {
      final String curr_page = the_page_buffer.get();
      my_page_count++;
      processPage(curr_page);
    }  
    catch (final InterruptedException e) 
    {
      return;
    }
    try 
    {
      Thread.sleep((int) Math.random() * MAX_SLEEP_TIME); // sleep for a randomly chosen time
    } 
    catch (final InterruptedException e) 
    {
      return;
    }
  }
}
